package org.toycode.solr.config;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement;
import org.toycode.solr.extractor.impl.MSExcelExtractor;
import org.toycode.solr.extractor.impl.MSWordExtractor;
import org.toycode.solr.extractor.impl.PdfExtractor;
import org.toycode.solr.extractor.impl.StringExtractor;
import org.toycode.solr.extractor.impl.TextFileExtractor;

/**
 * This class depicts the configuration of unmarshaled holder for file config.xml,
 * and loads the config.xml file.
 *
 * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
 * @version 1.0.0.4, Aug 27, 2009
 */
@XmlRootElement(name = "solr-service")
final public class Config {

    public static Config solrSvcConfig;
    /**
     * property extractor configurations.
     */
    @XmlElements(@XmlElement(type = Extractor.class,
                             name = "property-extractor"))
    public List<Extractor> extractors;
    /**
     * types of these entities need to be indexed and searched.
     */
    @XmlElements(@XmlElement(type = Entity.class, name = "entity"))
    public List<Entity> entities;

    /**
     * Generates a sample config.xml.
     *
     * @throws JAXBException jaxb exception
     */
    public static void genSampleConfig() throws JAXBException {
        final JAXBContext jc = JAXBContext.newInstance(Config.class);
        final Marshaller m = jc.createMarshaller();
        solrSvcConfig = new Config();
        // types: 
        final List<Entity> typeList = new ArrayList<Entity>();
        solrSvcConfig.entities = typeList;

        final Entity dummy1 = new Entity();
        dummy1.duplicatedUniqueKeyOperation = Entity.UNIQUE_KEY_UPDATE_OPERTION;
        dummy1.clazz = "org.toycode.solr.entity.Dummy1";
        dummy1.displayName = "Dummy1";
        final List<Prop> dummy1Props = new ArrayList<Prop>();

        final Prop dummy1Prop1 = new Prop();
        dummy1Prop1.displayName = "dummy1 prop display name 1 for title";
        dummy1Prop1.name = "title";
        dummy1Prop1.type = "string";
        dummy1Props.add(dummy1Prop1);

        final Prop dummy1Prop2 = new Prop();
        dummy1Prop2.displayName = "dummy1 prop display name 2 for strings";
        dummy1Prop2.name = "strings";
        dummy1Prop2.type = "strings";
        dummy1Props.add(dummy1Prop2);

        final Prop dummy1Prop3 = new Prop();
        dummy1Prop3.displayName = "dummy1 prop display name 3 for ms word paths";
        dummy1Prop3.name = "msWordFilePaths";
        dummy1Prop3.type = "ms_words";
        dummy1Props.add(dummy1Prop3);

        final Prop dummy1Prop4 = new Prop();
        dummy1Prop4.displayName =
                "dummy1 prop display name 4 for text file paths";
        dummy1Prop4.name = "textFilePaths";
        dummy1Prop4.type = "texts";
        dummy1Props.add(dummy1Prop4);

        final Prop dummy1Prop5 = new Prop();
        dummy1Prop5.displayName =
                "dummy1 prop display name 5 for pdf file path";
        dummy1Prop5.name = "pdfFilePath";
        dummy1Prop5.type = "pdf";
        dummy1Props.add(dummy1Prop5);

        final Prop dummy1Prop6 = new Prop();
        dummy1Prop6.displayName =
                "dummy1 prop display name 6 for ms excel file path";
        dummy1Prop6.name = "msExcelFilePath";
        dummy1Prop6.type = "ms_excel";
        dummy1Props.add(dummy1Prop6);

        dummy1.props = dummy1Props;

        typeList.add(dummy1);
        ////////////////////////////////////////////////////////////////////////
        final Entity dummy2 = new Entity();
        dummy2.duplicatedUniqueKeyOperation = Entity.UNIQUE_KEY_PASS_OPERTION;
        dummy2.clazz = "org.toycode.solr.entity.Dummy2";
        dummy2.displayName = "Dummy2";
        final List<Prop> dummy2Props = new ArrayList<Prop>();

        final Prop dummy2Prop1 = new Prop();
        dummy2Prop1.displayName = "dummy2 prop display name 1 for lead name";
        dummy2Prop1.name = "leadName";
        dummy2Prop1.type = "string";
        dummy2Props.add(dummy2Prop1);

        final Prop dummy2Prop2 = new Prop();
        dummy2Prop2.displayName = "dummy2 prop display name 2 for strings";
        dummy2Prop2.name = "strings";
        dummy2Prop2.type = "strings";
        dummy2Props.add(dummy2Prop2);

        dummy2.props = dummy2Props;

        typeList.add(dummy2);
        // extractors:
        final Extractor msExcelExtractor = new Extractor();
        msExcelExtractor.clazz = MSExcelExtractor.class;
        msExcelExtractor.extractableTypes = Arrays.asList("ms_excel",
                                                          "ms_excels");

        final Extractor msWordExtractor = new Extractor();
        msWordExtractor.clazz = MSWordExtractor.class;
        msWordExtractor.extractableTypes = Arrays.asList("ms_word", "ms_words");

        final Extractor pdfExtractor = new Extractor();
        pdfExtractor.clazz = PdfExtractor.class;
        pdfExtractor.extractableTypes = Arrays.asList("pdf", "pdfs");

        final Extractor stringExtractor = new Extractor();
        stringExtractor.clazz = StringExtractor.class;
        stringExtractor.extractableTypes = Arrays.asList("string", "strings");

        final Extractor textExtractor = new Extractor();
        textExtractor.clazz = TextFileExtractor.class;
        textExtractor.extractableTypes = Arrays.asList("text", "texts");

        solrSvcConfig.extractors = Arrays.asList(msExcelExtractor,
                                                 msWordExtractor,
                                                 pdfExtractor,
                                                 stringExtractor,
                                                 textExtractor);

        m.setProperty(m.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        m.marshal(solrSvcConfig, new File("solr-service.xml"));
    }

    /**
     * Loads the config.xml. 
     *
     * @throws JAXBException jaxb exception
     */
    public synchronized static void load() throws JAXBException {
        final JAXBContext jc = JAXBContext.newInstance(Config.class);
        final Unmarshaller m = jc.createUnmarshaller();
        final String home = System.getProperty("solr.solr.home");

        Config.solrSvcConfig = (Config) m.unmarshal(new File(home + "/../solr-service.xml"));
    }
}
